#ifndef DATABASE_H
#define DATABASE_H

#include <QString>
#include <QList>

#include "earthdawn.h"
#include "skill.h"
#include "spell.h"
#include "talent.h"
#include "specialization.h"
#include "discipline.h"

class Database
{
private:
    template<typename T>
    static QList<T> init(const QString& rootElement);

    static QList<Discipline> initDisciplines();

    static void initTables();

    static QList<Talent> _talents;
    static QList<Skill> _skills;
    static QList<Spell> _spells;
    static QList<Specialization> _specializations;
    static QList<Discipline> _disciplines;

    static QVector<ed::DicePool> LEVEL_DICE;
    static QVector<int> ATTRIBUTE_LEVEL;
    static QVector<QMap<ed::ResultDegree,int> > RESULT_DEGREE;
    static QVector<QMap<ed::Characteristic,int> > CHARACTERISTICS;
    static QMap<ed::Characteristic,ed::Attribute> CHARACTERISTIC_ATTRIBUTE;
    static QMap<ed::Race,QMap<ed::Attribute,int> > RACIAL_MODIFIERS;
    static QVector<int> ATTRIBUTE_COSTS;
    static QMap<ed::Race,int> MOVEMENT_DEXTERITY_MODIFIER;
    static QVector<int> ATTRIBUTE_LEGEND_COST;
    static QVector<int> SKILL_LEGEND_COST;
    static QVector<QVector<int> > TALENT_LEGEND_COST;
    static QVector<int> MINIMUM_TALENT_RANK_REQUIREMENTS;
    static QMap<ed::Race,QPair<int,int> > KARMA;
public:
    static const int MAXIMUM_SKILL_RANK = 10;
    static const int MAXIMUM_TALENT_RANK = 15;
    static const int MAXIMUM_ATTRIBUTE_AUGMENTATION = 5;

    static void init();
    static QList<Talent> talents(const QString& pattern);

    static ed::DicePool dicePool(int level);
    static ed::ResultDegree resultDegree(int difficulty, int testResult);
    static int requiredResult(int difficulty,ed::ResultDegree resultDegree);
    static int level(int attributeValue);
    static int characteristicValue(ed::Characteristic c, int attributeValue);
    static ed::Attribute characteristicAttribute(ed::Characteristic c);
    static int racialModifier(ed::Race r, ed::Attribute a);
    static int attributeCost(int attributeValue);
    static int attributeLegendCost(int attributeIncrease);
    static int movementDexterityModifier(ed::Race r);
    static int skillLegendCost(int rank);
    static int talentLegendCost(int rank,int circle);
    static int specializationLegendCost(const Specialization& s);
    static int minimumTalentRankRequirement(int circle);
    static int minimumTalentCountRequirement(int circle);

    static QList<Talent> talents() { return _talents; }
    static Talent talent(const QString& name);

    static QList<Skill> skills() { return _skills; }
    static Skill skill(const QString& name);

    static QList<Spell> spells() { return _spells; }
    static QList<Spell> spells(const Discipline& d, int circle);
    static QList<Specialization> specializations() { return _specializations; }

    static QList<Discipline> disciplines() { return _disciplines; }
    static Discipline discipline(const QString &name);

    static int karmaLevel(ed::Race r);
    static int maximumKarma(ed::Race r);

    static QString randomName(const QString& sourceBase);
};

#endif // DATABASE_H
